home *** CD-ROM | disk | FTP | other *** search
- ;$Author: DCODY $
- ;$Date: 01 Dec 1992 11:18:02 $
- ;$Header: X:/sccs/mixers/mixers.asv 1.4 01 Dec 1992 11:18:02 DCODY $
- ;$Log: X:/sccs/mixers/mixers.asv $
- ;
- ; Rev 1.4 01 Dec 1992 11:18:02 DCODY
- ; corrected a misnamed register. Changed the code to support revD
- ; mv508 mixer problem
- ;
- ; Rev 1.3 24 Nov 1992 12:04:46 DCODY
- ; renamed the 510 table to 508 table
- ;
- ; Rev 1.2 28 Jun 1992 11:36:42 DCODY
- ; fixed FM split, and made SB channel assigment changes on entry to SETMIXER
- ;
- ; Rev 1.1 23 Jun 1992 16:45:28 DCODY
- ; PAS2 update
- ;
- ; Rev 1.0 15 Jun 1992 09:41:36 BCRANE
- ; Initial revision.
- ;$Logfile: X:/sccs/mixers/mixers.asv $
- ;$Modtimes$
- ;$Revision: 1.4 $
-
- Title MIXERS -- Games Authors interface to MIXER/VOLUME/CROSS/FILTER
- page 64,131
-
- ; /*\
- ;---|*|----====< MIXERS >====----
- ;---|*|
- ;---|*| This module contains the code for supporting the mixers,filter,
- ;---|*| volume control, and PCM I/O.
- ;---|*|
- ; |*| Media Vision, Inc. Copyright (c) 1991, All Rights Reserved
- ;---|*|
- ; \*/
- ;
- if1
- %out ***********************************************************
- %out * *
- %out * ----====< Programming Caveat >====---- *
- %out * *
- %out * This code is provided as documentation ONLY. Attempting *
- %out * to use this in your program will make you hardware *
- %out * dependent!!!. Please use the identical API located in *
- %out * in MVHxLIB for mixer control. Here are the library *
- %out * function names: *
- %out * *
- %out * int (far *MVSetMixerFunction) (); *
- %out * int (far *MVSetVolumeFunction) (); *
- %out * int (far *MVSetFilterFunction) (); *
- %out * int (far *MVSetCrossChannel) (); *
- %out * int (far *MVGetMixerFunction) (); *
- %out * int (far *MVGetVolumeFunction) (); *
- %out * int (far *MVGetFilterFunction) (); *
- %out * int (far *MVGetCrossChannel) (); *
- %out * int (far *MVRealSoundSwitch) (); *
- %out * int (far *MVFMSplitSwitch) (); *
- %out * *
- %out ***********************************************************
- .err
- endif
-
- ;
- ; /*\
- ;---|*|
- ;---|*|----=======================================================---------
- ;---|*|----====< MVSOUND.SYS function table entry conditions:
- ;---|*|----=======================================================---------
- ;---|*|
- ;---|*| This function returns a segment:offset to the table of 10 functions
- ;---|*| The table is made up of 32 bit pointers to the ten far routines.
- ;---|*| Each routine has different register requirements:
- ;---|*|
- ;---|*| Function #1 Set a Mixer.
- ;---|*|
- ;---|*| Entry Condition:
- ;---|*| BX is the setting (0% - 100%)
- ;---|*| CX is the mixer select (BI_OUTPUTMIXER | BI_INPUTMIXER)
- ;---|*| DX is the channel (ex: BI_L_FM, BI_R_FM, etc.)
- ;---|*|
- ;---|*| Exit Condition:
- ;---|*| All other registers are unchanged.
- ;---|*|
- ;---|*| Function #2 Set the Volume/Equalizer device.
- ;---|*|
- ;---|*| Entry Condition:
- ;---|*| BX is the setting (0% - 100%)
- ;---|*| CX is the volume channel select:
- ;---|*|
- ;---|*| BI_VOLLOUD
- ;---|*| BI_VOLENHANCE
- ;---|*| BI_VOLBASS
- ;---|*| BI_VOLTREBLE
- ;---|*| BI_VOLLEFT
- ;---|*| BI_VOLRIGHT
- ;---|*|
- ;---|*| Since some of the devices are swithes, a 0% turns it
- ;---|*| off, and a 100% turns it on. The switches are:
- ;---|*|
- ;---|*| BI_VOLLOUD -- ENHANCED STEREO switch
- ;---|*| BI_VOLENHANCE -- LOUDNESS switch
- ;---|*|
- ;---|*| Exit Condition:
- ;---|*| All other registers are unchanged.
- ;---|*|
- ;---|*| Function #3 Set the Filter.
- ;---|*|
- ;---|*| Entry Condition:
- ;---|*| BX is a new setting (0% - 100%)
- ;---|*|
- ;---|*| 0% filters out anything higher than 0k hz (is mute)
- ;---|*| 100% filters out anything higher than 20 khz
- ;---|*|
- ;---|*| Exit Condition:
- ;---|*| All other registers are unchanged.
- ;---|*|
- ;---|*| Function #4 Set the Cross Channel.
- ;---|*|
- ;---|*| Entry Condition:
- ;---|*| BX holds the new cross channel mask bits:
- ;---|*|
- ;---|*| 00000001b Right to Right
- ;---|*| 00000010b Left to Right
- ;---|*| 00000100b Right to Left
- ;---|*| 00001000b Left to Left
- ;---|*|
- ;---|*| A set bit turns ON the connection.
- ;---|*| A clear bit turns OFF the connection.
- ;---|*|
- ;---|*| Exit Condition:
- ;---|*| All other registers are unchanged.
- ;---|*|
- ;---|*| Function #5 Get a Mixer setting.
- ;---|*|
- ;---|*| Entry Condition:
- ;---|*| CX is the mixer select (BI_OUTPUTMIXER | BI_INPUTMIXER)
- ;---|*| DX is the channel (ex: BI_L_FM, BI_R_FM, etc.)
- ;---|*|
- ;---|*| Exit Condition:
- ;---|*| BL is the setting (0% - 100%)
- ;---|*| BH is 0 for off, FF for on.
- ;---|*| All other registers are unchanged.
- ;---|*|
- ;---|*| Function #6 Get the Volume/Equalizer setting.
- ;---|*|
- ;---|*| Entry Condition:
- ;---|*| CX is the volume channel select:
- ;---|*|
- ;---|*| BI_VOLLOUD
- ;---|*| BI_VOLENHANCE
- ;---|*| BI_VOLBASS
- ;---|*| BI_VOLTREBLE
- ;---|*| BI_VOLLEFT
- ;---|*| BI_VOLRIGHT
- ;---|*| BI_VOLMODE
- ;---|*|
- ;---|*| Since some of the devices are swithes, a 0% turns it
- ;---|*| off, and a 100% turns it on. The switches are:
- ;---|*|
- ;---|*| BI_VOLLOUD -- ENHANCED STEREO switch
- ;---|*| BI_VOLENHANCE -- LOUDNESS switch
- ;---|*|
- ;---|*| Exit Condition:
- ;---|*| BX is the setting (0% - 100%)
- ;---|*| All other registers are unchanged.
- ;---|*|
- ;---|*| Function #7 Get the Filter setting.
- ;---|*|
- ;---|*| Entry Condition:
- ;---|*| None
- ;---|*|
- ;---|*| Exit Condition:
- ;---|*| BX is a new setting (0% - 100%)
- ;---|*| 0% filters out anything higher than 0k hz (is mute)
- ;---|*| 100% filters out anything higher than 20 khz
- ;---|*|
- ;---|*| All other registers are unchanged.
- ;---|*|
- ;---|*| Function #8 Get the Cross Channel setting
- ;---|*|
- ;---|*| Entry Condition:
- ;---|*| None
- ;---|*|
- ;---|*| Exit Condition:
- ;---|*| BX holds the new cross channel mask bits:
- ;---|*|
- ;---|*| 00000001b Right to Right
- ;---|*| 00000010b Left to Right
- ;---|*| 00000100b Right to Left
- ;---|*| 00001000b Left to Left
- ;---|*|
- ;---|*| A set bit turns ON the connection.
- ;---|*| A clear bit turns OFF the connection.
- ;---|*|
- ;---|*| All other registers are unchanged.
- ;---|*|
- ;---|*| Function #9 Get/Set the Real Sound bit.
- ;---|*|
- ;---|*| Entry Condition:
- ;---|*| BX may hold 0 to turn off realsound, 100 to turn it on.
- ;---|*| CX determines if the switch is read or written. If cx
- ;---|*| is 0, the switch is read. If cx is not zero, the
- ;---|*| switch is written.
- ;---|*|
- ;---|*| Exit Condition:
- ;---|*| If the switch is read, BX holds 0 for off, 100 for on.
- ;---|*| All other registers are unchanged.
- ;---|*|
- ;---|*| Function #10 Get/Set the Split FM chips bit.
- ;---|*|
- ;---|*| Entry Condition:
- ;---|*| BX may hold 0 to split the chips, 100 to have mono chips
- ;---|*| CX determines if the switch is read or written. If cx
- ;---|*| is 0, the switch is read. If cx is not zero, the
- ;---|*| switch is written.
- ;---|*|
- ;---|*| Exit Condition:
- ;---|*| If the switch is read, BX holds 0 for split, 100 for mono.
- ;---|*| All other registers are unchanged.
- ;---|*|
- ; \*/
-
- ;
- ; The following equate sets up the compiled model size for this code:
- ;
- MODELSIZE equ 0
-
- include model.inc
- include masm.inc ; masm equates, etc
- include common.inc ; hardware equates module
- include state.inc ; state table
- include binary.inc ; int2f binary interface module
-
- .code
- assume ds:@code
- assume es:@code
-
- ;
- ; The following address is the entrypoint into the static mixer driver.
- ; This driver was provided as the static linked mixer driver embedded in
- ; MIXERC.C. This code compiles into a .COM format, then is translated into
- ; a header file to be included into MIXERC.C.
- ;
- org 0h ; The original driver worked
- ; with a zero offset.
- public StartingAddress ; The driver was initialized by
- StartingAddress label far ; a far call to offset 0 of the driver.
-
- jmp near ptr doinit ; go do it...
-
- db 0 ; filler to align on next dword
-
- signature db "MVPROAS01" ; 8 byte signature
-
-
- ; /*\
- ;---|*|--------------------====< Data Section >====--------------------
- ; \*/
-
- FunctionTable label near
- smixerfunc dd offset dosetmixer ; set the mixers
- svolumefunc dd offset dosetvolume ; set the volume
- sfilterfunc dd offset dosetfilter ; set the filter
- scrossfunc dd offset dosetcross ; set the cross channel
- gmixerfunc dd offset dogetmixer ; get the mixers
- gvolumefunc dd offset dogetvolume ; get the volume
- gfilterfunc dd offset dogetfilter ; get the filter
- gcrossfunc dd offset dogetcross ; get the cross channel
- realsound dd offset dorealsound ; get/set the realsound bit
- fmsplit dd offset dofmsplit ; get/set the FM split bit
-
- TheDMAChannel db DEFAULTDMA ; default DMA channel
- TheIRQChannel db DEFAULTIRQ ; default IRQ channel
-
- ;
- ; These variable hold the current mixer hardware state
- ;
- _inmixertbl dw 16 dup(0f0fh) ; input mixer indexes, settings
- _outmixertbl dw 16 dup(0f0fh) ; output mixer indexes, settings
- _currmixer db 16 dup(0fh) ; pointer to the other tables
- _voltbl dw 8 dup(000fh) ; total volume indexes, settings
- _filtidx db 0 ; filter index (0 - 6)
-
- HardwareShadowTable MVState <0>
- mvhwShadowPointer dd 0 ; far pointer to the state table
- mvhwFunctionTable dd 0 ; far pointer to the function table
-
- HardwareType dw 0 ; hardware feature bits
- ORIGPAS equ 0000000000000000b ; all feature bits are zero
- bMVA508 equ 0000000000000001b ; new mixer chip
- CDPC equ 0000000100000000b ; CDPC installed at original address
- PAS16 equ 0000001000000000b ; PAS16 installed at original address
- PAS8 equ 0000010000000000b ; PAS8 installed at original address
-
- sbleft db 0 ; SB left mixer connection
- sbright db 0 ; SB right mixer connection
-
- ;
- ; a table of maximum physical settings for each of the volume control device.
- ;
- _voltblmax db 02
- db 03
- db EQUALIZERMAX
- db EQUALIZERMAX
- _volleftmax db ? ; volume max changes between
- _volritmax db ? ; mixer chips
- db 06
- db 00
- ;
- ; a linear table of filter values - from mute to high for the 8 bit filter
- ;
- tableof label byte
- db 000000b ; mute - goes to PC speaker
- db 100100b ; 20hz to 2.9khz
- db 111001b ; 20hz to 5.9khz
- db 110001b ; 20hz to 8.9khz
- db 101001b ; 20hz to 11.9khz
- db 100010b ; 20hz to 15.9khz
- db 100001b ; 20hz to 17.8khz
-
- ;
- ; National Semi's Mixer Volume settings (0 - 12)
- ;
- mixersettings label byte
- db 0 ; level 0
- db 20H ; level 1
- db 10H ; level 2
- db 08H ; level 3
- db 04H ; level 4
- db 02H ; level 5
- db 12H ; level 6
- db 2AH ; level 7
- db 16H ; level 8
- db 01H ; level 9
- db 29H ; level A
- db 1DH ; level B
- db 2FH ; level C
-
-
- ; /*\
- ;---|*|--------------------====< Code Section >====--------------------
- ; \*/
-
- ; /*\
- ;---|*|------------------------==================-------------------------
- ;---|*|------------------------====< doinit >====-------------------------
- ;---|*|------------------------==================-------------------------
- ;---|*|
- ;---|*| This routine is only called if the DOS driver is not loaded, so
- ;---|*| we must init the various stuff...
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| None
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| DX:AX point to the function table
- ;---|*| BX holds the DMA channel #
- ;---|*| CX holds the IRQ channel #
- ;---|*|
- ; \*/
-
- invmso_done db 0 ; perform this code just once!
-
- public doinit
- doinit proc far
- push ds
-
- push cs ; all data is stored locally.
- pop ds
- ;
- ; perform the hardware code initialization
- ; this code can only be processed once
- ;
- cmp [invmso_done],0 ; have we been here?
- jjnz inmv_done ; yes, don't do this again
- inc [invmso_done] ; no, so pass by just once
- ;
- ; determine the hardware and setup for default stand-alone operation
- ;
- mov bx,ORIGPAS ; bx holds the flags
-
- mov dx,INTRCTLR ; check the board rev bits
- in al,dx
- test al,fICrevbits ; non-zero means we have new hardware
- jz foundthehardware
-
- mov bx,CDPC
- mov dx,MASTERMODRD ; check for the CDPC
- in al,dx
- test al,bMMRDmsmd ; master/slave bit set?
- jnz foundthehardware
-
- mov bx,PAS8 ; check for the 8 bit card
- mov dx,SLAVEMODRD ; check for the CDPC
- in al,dx
- test al,bSMRDdactyp ; 16 bit DAC?
- jz foundthehardware ; no, so it's the PAS16 card
- mov bx,PAS16+bMVA508 ; check for the 8 bit card
- ;
- foundthehardware:
- mov [HardwareType],bx ; save the type
-
- test bx,PAS16 ; is a PAS16 with the new mixer?
-
- mov bl,MVVOLUMEMAX ; (default to new mixer)
- mov ax,(L_FREE*256)+R_FREE ; SB is FREE for mva508 types
-
- jnz @F
-
- mov bl,NSVOLUMEMAX ; no, use the NS mixer data
- mov ax,(L_SPEAKER*256)+R_SPEAKER ; SB is SPEAKER for others
- ;
- @@:
- mov [_volleftmax],bl ; save the maximum volume setting
- mov [_volritmax],bl
- mov [sbleft],ah ; save the sb connections
- mov [sbright],al
- ;
- ; we must complete the 32 bit addresses in the vector table
- ;
- push es
- push di
-
- mov ax,cs ; ax holds the segment for storing
- lea bx,FunctionTable
- mov wptr [mvhwFunctionTable+0],bx ; save a copy of the table
- mov wptr [mvhwFunctionTable+2],ax ; pointer in our code
-
- mov es,ax ; es:di points to the local table
- mov di,bx
- mov cx,10 ; update just ten entries
- cld
- ;
- @@:
- inc di ; pass the offset
- inc di
- stosw ; store the segment
- loop @B
-
- pop di
- pop es
- ;
- ; setup a pointer to our local hardware state table
- ;
- lea bx,HardwareShadowTable
- mov wptr [mvhwShadowPointer+0],bx
- mov wptr [mvhwShadowPointer+2],cs
- ;
- ; find the int 2F interface
- ;
- mov ax,0bc00h ; load the registers to check if
- mov bx,'??' ; MVSOUND.SYS is loaded.
- sub cx,cx ; this is a unique enough approach
- sub dx,dx
-
- int 2fh ; get the response
-
- xor bx,cx ; merge the response into BX
- xor bx,dx
- cmp bx,'MV' ; is the int 2F interface here?
- jnz inmv_done ; no, exit home
- ;
- ; the int 2F interface is there, so get the state table.
- ;
- mov ax,0bc02h ; get the state table pointer
- int 2fh
- mov wptr [mvhwShadowPointer+0],bx
- mov wptr [mvhwShadowPointer+2],dx
-
- mov ax,0bc03h ; get the function pointer
- int 2fh
- mov wptr [mvhwFunctionTable+0],bx
- mov wptr [mvhwFunctionTable+2],dx
-
- mov ax,0bc04h ; get the DMA and IRQ numbers
- int 2fh
- mov TheDMAChannel,bl ; save the correct DMA & IRQ
- mov TheIRQChannel,cl
- ;
- inmv_done:
- mov ax,wptr [mvhwFunctionTable+0]
- mov dx,wptr [mvhwFunctionTable+2]
-
- pop ds
- retf
-
- doinit endp
-
- ;
- ; /*\
- ;---|*|-------------------------===================-------------------------
- ;---|*|-----------------------====< dogetcross >====-------------------------
- ;---|*|-------------------------===================-------------------------
- ;---|*|
- ;---|*| Return the Cross channel mask
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| None
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| BX holds the old cross channel mask bits:
- ;---|*|
- ;---|*| 00000001b Right to Right
- ;---|*| 00000010b Right to Left
- ;---|*| 00000100b Left to Right
- ;---|*| 00001000b Left to Left
- ;---|*|
- ;---|*| A set bit means the connection is ON.
- ;---|*| A clear bit means the connection is OFF.
- ;---|*|
- ; \*/
-
- public dogetcross
- dogetcross proc far
-
- push ax ; save everything
- push cx
- push dx
- push ds
-
- push es
- push di
-
- les di,cs:[mvhwShadowPointer] ; get the pointer
- mov bl,es:[di._crosschannel]
- and bx,0000fh
-
- pop di
- pop es
- ;
- far_return_less_bx label near
- pop ds
- pop dx
- pop cx
- pop ax
- retf
-
- dogetcross endp
-
- ;
- ; /*\
- ;---|*|-------------------------===================-------------------------
- ;---|*|-----------------------====< dosetcross >====-------------------------
- ;---|*|-------------------------===================-------------------------
- ;---|*|
- ;---|*| Load a new cross channel mask
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| BX holds the new cross channel mask bits:
- ;---|*|
- ;---|*| 00000001b Right to Right
- ;---|*| 00000010b Right to Left
- ;---|*| 00000100b Left to Right
- ;---|*| 00001000b Left to Left
- ;---|*|
- ;---|*| A set bit turns ON the connection.
- ;---|*| A clear bit turns OFF the connection.
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| None
- ;---|*|
- ; \*/
-
- public dosetcross
- dosetcross proc far
-
- push ax
- push bx
- push cx
- push dx
- push ds
-
- push es
- push di
- pushf
-
- les di,cs:[mvhwShadowPointer] ; get the pointer
- mov dx,CROSSCHANNEL
- xchg ax,bx
-
- cli ; kill ints until popf
- mov ah,es:[di._crosschannel]
- and ax,0f00fh
- or al,ah
- mov es:[di._crosschannel],al
- out dx,al
-
- popf
- pop di
- pop es
-
- jmp far_return
-
- dosetcross endp
-
- ;
- ; /*\
- ;---|*|------------------------====================------------------------
- ;---|*|----------------------====< dogetfilter >====------------------------
- ;---|*|------------------------====================------------------------
- ;---|*|
- ;---|*| Return the current filter settings, from 0 to 100 %, where
- ;---|*| 0 is mute and 100 % is CD quality
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| None
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| BX holds the value
- ;---|*|
- ; \*/
-
- public dogetfilter
- dogetfilter proc far
-
- push ax ; save everything
- push cx
- push dx
- push ds
-
- push es
- push di
- les di,cs:[mvhwShadowPointer] ; get the pointer
- mov al,es:[di._audiofilt]
- pop di
- pop es
-
- sub bx,bx ; ax starts with mute
- test al,20h ; mute bit clear
- jz dogefi_done ; yes, we have the value
-
- mov bx,17
- cmp al,24h ; male voice?
- jz dogefi_done
-
- mov bx,34
- cmp al,39h ; Telephone?
- jz dogefi_done
-
- mov bx,50
- cmp al,31h ; AM Radio?
- jz dogefi_done
-
- mov bx,67
- cmp al,29h ; FM Radio?
- jz dogefi_done
-
- mov bx,84
- cmp al,22h ; Cassette?
- jz dogefi_done
-
- mov bx,100 ; CD = 100 %
-
- dogefi_done:
- jmp short far_return_less_bx
-
- dogetfilter endp
-
- ;
- ; /*\
- ;---|*|------------------------====================------------------------
- ;---|*|----------------------====< dosetfilter >====------------------------
- ;---|*|------------------------====================------------------------
- ;---|*|
- ;---|*| Set the filter to a setting from 0 to 100 %, where 0 is mute, 100 %
- ;---|*| is no filtering at all.
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| BX holds the value
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| None
- ;---|*|
- ; \*/
-
- public dosetfilter
- dosetfilter proc far
- push ax ; save everything
- push bx
- push cx
- push dx
- push ds
-
- push cs ; all data is stored locally.
- pop ds
-
- mov ax,6 ; translate 0-100 % into 0-6
- mov bh,ah ; flush the top half
- xchg ax,bx
- or ax,ax ; if mute, skip the math...
- jz @F
- mul bx
- mov bl,100
- div bx ; ax holds the new setting
- ;
- @@:
- push ax
- call SetFilter
- pop ax
- jmp far_return
-
- dosetfilter endp
-
- ;
- ; /*\
- ;---|*|------------------------===================------------------------
- ;---|*|----------------------====< dogetmixer >====------------------------
- ;---|*|------------------------===================------------------------
- ;---|*|
- ;---|*| Return the channel setting in either the input or output mixer.
- ;---|*| The return value will be 0 - 100 %
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| CX holds the mixer select (BI_OUTPUTMIXER or BI_INPUTMIXER)
- ;---|*| DX holds the channel (ex: L_LEFTFM, R_LEFTFM, etc.)
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| BX returns the volume (0 - 100%)
- ;---|*|
- ; \*/
-
- public dogetmixer
- dogetmixer proc far
- push ax ; save everything
- push cx
- push dx
- push ds
-
- push cs ; all data is stored locally.
- pop ds
-
- mov bx,dx
- and bx,0fh ; make sure the channel is legit
- lea ax,_inmixertbl
- cmp cx,BI_INPUTMIXER
- jz @F
- lea ax,_outmixertbl
- ;
- @@:
- sub cl,_currmixer[bx] ; get the current channel selection
- add bx,ax
- mov al,[bx] ; get the current value
-
- mov bx,100 ; translate 0-31 into 0-100%
- cbw
- mul bx
- or ax,ax
- jz @F
- mov bl,31
- div bx ; ax holds the new setting
- ;
- @@:
- call rounduppct ; psuedo round up
- xchg ax,bx ; bl holds the result
- cmp cl,1 ; carry set if Z, clear if NZ
- sbb bh,bh ; bh holds the ON/OFF flag
- jmp far_return_less_bx
-
- dogetmixer endp
-
- ;
- ; /*\
- ;---|*|------------------------===================------------------------
- ;---|*|----------------------====< dosetmixer >====------------------------
- ;---|*|------------------------===================------------------------
- ;---|*|
- ;---|*| Set an input or output mixer channel from 0 to 100%
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| BX holds the volume (0 - 100%)
- ;---|*| CX holds the mixer select (BI_OUTPUTMIXER or BI_INPUTMIXER)
- ;---|*| DX holds the channel (ex: L_LEFTFM, R_LEFTFM, etc.)
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| None
- ;---|*|
- ; \*/
-
- public dosetmixer
- dosetmixer proc far
-
- push ax ; save everything
- push bx
- push cx
- push dx
- push ds
-
- push cs ; all data is stored locally.
- pop ds
- ;
- ; special case the variable channel assignments here...
- ;
- cmp cl,BI_L_SBDAC ; if left SB
- jnz @F
- mov cl,[sbleft] ; force it to be true
- jmp chgdone
- ;
- @@:
- cmp cl,BI_R_SBDAC ; if right SB
- jnz @F
- mov cl,[sbright] ; force it to be true
- ;
- chgdone:
- ;
- ; perform the mixer settings now...
- ;
- push dx ; save the channels
- push dx ; and one more copy
-
- mov ax,31 ; translate 0-100% into 0-31
- mov bh,ah ; flush the top half
- xchg ax,bx
- or ax,ax ; if mute, skip the math...
- jz @F
- mul bx
- mov bl,100
- div bx ; ax holds the new setting
- ;
- @@:
- pop bx ; get the channel
- and bx,0fh ; make sure the channel is legit
-
- lea dx,_inmixertbl
- mov ch,INPUTMIXER
- cmp cl,BI_INPUTMIXER
- jz @F
- lea dx,_outmixertbl
- mov ch,OUTPUTMIXER
- ;
- @@:
- mov _currmixer[bx],cl ; save the channel selection
- add bx,dx
-
- call FetchMixLevel ; on the National chip, convert to 0-12
- mov [bx],ax ; save the new value
-
- xchg ah,al ; let ax hold the converted value
- cbw
-
- mov cl,ch ; cl holds the parameter
- mov bx,ax ; bx holds the channel setting
- pop ax ; ax holds the channel #
- call SetMixer ; set the mixer
- ;
- far_return label near ; here for convienience sake
- pop ds
- pop dx
- pop cx
- pop bx
- pop ax
- retf
-
- dosetmixer endp
-
- ;
- ; /*\
- ;---|*|------------------------====================------------------------
- ;---|*|----------------------====< dogetvolume >====------------------------
- ;---|*|------------------------====================------------------------
- ;---|*|
- ;---|*| Return with one of the volume register settings
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| CX holds the channel
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| BX holds the value
- ;---|*|
- ; \*/
- ;
- .errnz VOLMUTE-40h ; volume devices have bit 6 set
- .errnz BI_VOLENHANCE-BI_VOLLOUD-1 ; LOUDNESS=0, ENHANCED=1
-
- public dogetvolume
- dogetvolume proc far
-
- push ax ; save everything
- push cx
- push dx
- push ds
-
- push cs ; all data is stored locally.
- pop ds
- ;
- ; convert the channel number to the table index
- ;
- and cx,07h ; make it legit
- mov bx,cx ; load the index into bx
- cmp cl,1 ; if it's BI_VOLLOUD, make it BI_VOLEHN...
- sbb ax,ax ; ax = ffff if 0, 0000 if 1
- adc bl,0 ; if bl = 40, bl++
- shl bx,1 ; word indexing...
-
- mov bx,[_voltbl+bx] ; get the setting
- ;
- ; convert the volume settings into 0 - 100 % values
- ;
- dec cx ; if 1, then it's loudness, enhanced
- jle dogvo_loudness ; go do it...
- mov al,12
- sub cl,2 ; if LE,then it's BASS or TREBLE scale
- jle dogvo_scale
- mov al,40
- ;
- ; volume or equalizer settings
- ;
- dogvo_scale:
- xchg ax,bx ; ax = the current setting, bx the max
- or ax,ax
- jz dogvo_done
- mov cx,100
- mul cx
- div bx
- jmp short dogvo_done
- ;
- ; loudness and enhanced buttons
- ;
- dogvo_loudness:
- not ax
- and al,1 ; al = 0 for volloud, 1 for enhanced
- inc al ; al = 1 for volloud, 2 for enhanced
-
- and al,bl ; al holds the bit
- neg al ; set carry on zero
- sbb al,al
- and ax,100 ; ax = 0 for off, 100 for on
- ;
- dogvo_done:
- call rounduppct ; psuedo rounding
- xchg ax,bx ; bx holds the result
- jmp far_return_less_bx
-
- dogetvolume endp
-
- ;
- ; /*\
- ;---|*|------------------------====================------------------------
- ;---|*|----------------------====< dosetvolume >====------------------------
- ;---|*|------------------------====================------------------------
- ;---|*|
- ;---|*| Set one of the volume register with stufff...
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| BX holds the value
- ;---|*| CX holds the channel
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| None
- ;---|*|
- ; \*/
- ;
- .errnz VOLMUTE-40h ; volume devices have bit 6 set
- .errnz BI_VOLENHANCE-BI_VOLLOUD-1 ; LOUDNESS=0, ENHANCED=1
-
- public dosetvolume
- dosetvolume proc far
-
- push ax ; save everything
- push bx
- push cx
- push dx
- push ds
-
- push cs ; all data is stored locally.
- pop ds
-
- sub bh,bh ; make sure its a low value
- ;
- ; convert the channel number to something close
- ;
- or cl,40h ; add in the National device select bit
- ;
- ; volume settings
- ;
- cmp cl,BI_VOLLEFT+40H
- jz dovo_volume
- cmp cl,BI_VOLRIGHT+40H
- jnz dovo_notvolume
- ;
- dovo_volume:
- mov al,[_volleftmax] ; xlat 0-100% to the physical max
- cbw
- xchg ax,bx
- or ax,ax
- jz dovo_sendit
- mul bx
- mov bl,100
- div bx
- jmp short dovo_sendit
- ;
- dovo_notvolume:
- ;
- ; bass/treble settings
- ;
- cmp cl,BI_VOLBASS+40H
- jz dovo_bass
- cmp cl,BI_VOLTREBLE+40H
- jnz dovo_not_basstreble
- ;
- dovo_bass:
- mov ax,12 ; xlat 0-100% to 0-12
- xchg ax,bx
- or ax,ax
- jz dovo_sendit
- mul bx
- mov bl,100
- div bx
- jmp short dovo_sendit
- ;
- dovo_not_basstreble:
- ;
- ; loudness and enhanced buttons
- ;
- mov ax,0fe01h ; load a mask for stripping/saving bits
- cmp cl,BI_VOLLOUD+40H ; loudness?
- jz dovo_loudness ; yes, use it
- cmp cl,BI_VOLENHANCE+40H ; enhanced?
- jnz dovo_bad ; no, bomb out...
- mov ax,0fd02h ; load a mask for stripping/saving bits
- ;
- dovo_loudness:
-
- or cl,01 ; calc the true volume register
- .errnz (VOLLOUDENH AND 0BFh) - 1 ; make sure the above ADD works
-
- and ah,byte ptr [_voltbl+2] ; get all other bits
- .errnz VOLLOUDENH-41h ; must be entry #2
-
- neg bl ; sets carry if not zero
- sbb bl,bl ; bl = 0000 if 0, else ffff for 1
- and al,bl
- or al,ah ; al holds the new value
- ;
- dovo_sendit:
- sub ch,ch ; guarrenteed goodness...
- sub ah,ah ; guarrenteed goodness...
- mov bx,cx ; bx holds the channel, ax the value
- xchg ax,bx ; for keeping the parameters straight...
- call SetVolume
- ;
- dovo_bad:
- jmp far_return
-
- dosetvolume endp
-
- ;
- ; /*\
- ;---|*|------------------===============================-----------------------
- ;---|*|----------------====< dorealsound/dofmsplit >======---------------------
- ;---|*|------------------===============================-----------------------
- ;---|*|
- ;---|*| Set/Get the realsound and FM bit settings
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| BX holds the 0 for off, ~0 for ON
- ;---|*| CX holds 0 to get, 1 to set the bit
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| BX may return the value
- ;---|*|
- ; \*/
- ;
- public dorealsound
- dorealsound proc far
-
- push ax ; save everything
- push cx
- push dx
- push ds
-
- mov ah,bMIspkrint ; realsound bit
-
- push cs ; all data is stored locally.
- pop ds
-
- push es
- push di
- les di,mvhwShadowPointer ; get the pointer
- ;
- finish_common_code:
- jcxz dogetrealorfm ; if not set, go get the bit
-
- push bx ; since this is a SET we can't flush bx
- ;
- ; create an AND / OR mask to set/clear the bit
- ;
- neg bx ; set carry if nonzero
- sbb al,al ; al = 0000 for 0, ffff for 1
- and al,ah ; al holds the OR bit mask
- not ah ; ah holds the AND bit mask
-
- mov dx,AUDIOMIXR
-
- pushf
- cli
-
- and ah,es:[di._audiomixr] ; get all but the realsound/fm bit
-
- or al,ah ; merge into the one bit
-
- out dx,al
- mov es:[di._audiomixr],al ; save the new bit
-
- popf
- pop bx ; restore bx
- jmp short dogetrealdone
- ;
- dogetrealorfm:
-
- and ah,es:[di._audiomixr] ; get the bit
- neg ah ; carry set if nonzero
- sbb bx,bx ; bx = ffff for ~0, 0000 for 0
- and bx,100 ; bx = 0 or 100%
- ;
- dogetrealdone:
- pop di
- pop es
- jmp far_return_less_bx
-
- ;
- ;----====< dofmsplit entrypoint >====----
- ;
-
- dofmsplit label far
- push ax ; save everything
- push cx
- push dx
- push ds
-
- mov ah,bMImonofm ; fm bit
-
- push cs ; all data is stored locally.
- pop ds
- ;
- ; check the different hardware versions.
- ;
- push es
- push di
- les di,mvhwShadowPointer ; get the pointer
-
- test es:[di._intrctlr],fICidbits ; rev 2+ ?
- jz finish_common_code ; no, handle as PAS1
- jcxz finish_common_code ; also, GETs will go that way...
- ;
- ; OPL3 board, so do the switch at the OPL3 chip
- ;
- mov ax,bx ; save BX
- neg ax ; set carry to turn off
- sbb ax,ax ; al = 0 for OFF, FF for ON
- and ah,1 ; ah = 0 for OFF, 01 for ON
- xor ah,1 ; flip for the OPL 3
- ;
- ; maintain compatibility with the old mixer setup.
- ;
- and al,bMImonofm ; save just that bit
-
- and es:[di._audiomixr],NOT bMImonofm ; flush the bit
- or es:[di._audiomixr],al ; maybe set the bit
-
- mov al,05h
- mov dx,RFMADDR ; write to the new bit in the OPL3
- out dx,al ; index first...
- inc dx
-
- in al,dx ; waste time...
- in al,dx ; waste time...
-
- mov al,ah ; data next...
- out dx,al
-
- jmp short dogetrealdone ; exit via common code
-
- dorealsound endp
-
- ;
- ; /*\
- ;---|*|----====< int SetCrossChannel >====----
- ;---|*|
- ;---|*| Output New Cross Channel Select Bits
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| AX holds the channel bit
- ;---|*| DX holds the state (0 or -1)
- ;---|*| DS holds our data segment
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| AX,DX modified.
- ;---|*| h/w channel select modified
- ;---|*|
- ; \*/
-
- public SetCrossChannel
- SetCrossChannel proc
- push es
- push di
- les di,mvhwShadowPointer ; get the pointer
-
- mov ah,al ; ah = AND mask al = XOR mask
- not ah
- and al,dl ; al = 00 to clear, else 0X to set
-
- mov dx,CROSSCHANNEL
-
- disable
-
- and ah,es:[di._crosschannel]
- xor al,ah
- out dx,al
- mov es:[di._crosschannel],al ; save the new value, & return the old
-
- enable
-
- pop di
- pop es
- ret
-
- SetCrossChannel endp
-
- ;
- ; /*\
- ;---|*|----====< void SetFilter (int setting ) >===----
- ;---|*|
- ;---|*| This routine selects a filter setting from mute to high freq filter.
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| AX is a value from 0 - 6
- ;---|*| DS holds our data segment
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| None
- ;---|*|
- ;---|*|
- ; \*/
-
- public SetFilter
- SetFilter proc
- push es
- push di
- les di,mvhwShadowPointer ; get the pointer
-
- mov bx,ax
- cmp bx,6 ; validate the user index
- ja sfbadval
-
- mov _filtidx,bl
- mov ah,tableof[bx] ; grab an appropriate value
- mov dx,AUDIOFILT ; and toss it out...
-
- disable
-
- mov al,es:[di._audiofilt] ; get the shadowed gates
-
- and al,not (fFIdatabits+fFImutebits) ; save the non-filter bits
- or al,ah ; merge in the filter bits
- out dx,al
-
- mov es:[di._audiofilt],al ; shadow it too...
-
- enable
- ;
- sfbadval:
- pop di
- pop es
- ret
-
- SetFilter endp
-
- ;
- ; /*\
- ;---|*|----====< void SetMixer >====----
- ;---|*|
- ;---|*| Set the selected channel within the MVA508 Mixers & Volume device
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| AX holds the channel (0 - 15)
- ;---|*| BX holds the volume (0 - 31)
- ;---|*| CL holds the device: OUTPUTMIXER or INPUTMIXER or DEFMIXER
- ;---|*| DS holds our data segment
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| AX,BX,CX,DX modified
- ;---|*|
- ; \*/
-
- public SetMixer
- SetMixer proc near
- push es
- push di
- les di,mvhwShadowPointer ; get the pointer
-
- xchg bx,ax ; bx = channel #, al = volume
- mov ah,al ; ah = real, al = simulated
-
- test [hardwaretype],bMVA508
- jjz nsSetMixer
- ;
- ; we scale down the mixer settings to make them
- ; sound more like the National part.
- ;
- mov ch,ah ; multiply the value by 1.25 We take
- shr ch,1 ; the value, divide in half, then
- shr ch,1 ; the value, divide in half, then
- add ah,ch ; add it back in.
- cmp ah,1Fh ; not maxed out, just use it...
- jbe @F
- mov ah,1Fh ; max it out...
- ;
- @@:
- ;
- ; send out the mixer channel #
- ;
- mov al,cs:mv508table[bx] ; get the true mixer channel
- mov dx,pAUDIOMIXR ; parallel mixer address
-
- push ax
-
- dec dx
- mov ah,al
- out dx,ax
- ;
- ; convert the mixer select from the National definition to the MVA508
- ;
- .errnz OUTPUTMIXER ; must always be zero
- .erre INPUTMIXER ; must always be non-zero
- .erre pmINPUTMIXER ; must always be non-zero
-
- pop ax
- neg cl ; CY if INPUT mixer, NC for OUTPUT mixer
- sbb al,al
- and al,pmINPUTMIXER ; al now holds the proper bit field
- or al,ah ; real mixer channel volume level
- mov ah,al
- out dx,ax
-
- mov es:[di._paudiomixr],al ; shadow it...
- ;
- semi_exit:
- pop di
- pop es
- ret
- ;
- ; National Semi Mixer setting code
- ;
- nsSetMixer:
- push ax ; save the channel setting
- push cx ; save the INPUTMIXER/OUTPUTMIXER bits
- ;
- ; send out the mixer channel #
- ;
- test cs:[hardwaretype],CDPC ; CDPC mixer L/R connections are
- jz @F ; backwards...
- mov bl,cs:[cdpcmixer+bx] ; We will straighten them out.
- @@:
- mov ah,bl ; restore the register #
- or ah,080h ; OR 080h d7=channel #
- or ah,cl ; merge in the mixer select
- call lmix ; (lvol looks for 80h)
- ;
- ; send out the mixer data
- ;
- pop cx ; get the INPUTMIXER/OUTPUTMIXER
- pop ax ; get the channel setting in AH
- or ah,cl ; merge in the mixer select
- call lmix
- ;
- _semi_exit:
- pop di
- pop es
- ret
- ;
- ; This table reverses the mixer settings so left is now right & visa versa.
- ;
- cdpcmixer label byte
- db 15 ; nothing
- db 08 ; Left FM
- db 09 ; Left input mixer
- db 10 ; Left External
- db 11 ; Left Internal
- db 12 ; Left Mic
- db 13 ; Left PCM
- db 14 ; Left Speaker
-
- db 0 ; nothing
- db 01 ; Right FM
- db 02 ; Right Input Mixer
- db 03 ; Right External
- db 04 ; Right Internal
- db 05 ; Right Mic
- db 06 ; Right PCM
- db 07 ; Right Speaker
-
- pmADMI equ <pmADDRSELECT+pmMIXERSELECT>
-
- mv508table label byte ;Ch #; PAS ; MVA508
- db 07+pmCHANNELL+pmADMI ; 0 ; L_FREE; 7 - Now the SB connect
- db 00+pmCHANNELL+pmADMI ; 1 ; L_FM ; 0
- db 01+pmCHANNELL+pmADMI ; 2 ; L_Mix ; 1
- db 02+pmCHANNELL+pmADMI ; 3 ; L_Ext ; 2
- db 03+pmCHANNELL+pmADMI ; 4 ; L_Int ; 4
- db 04+pmCHANNELL+pmADMI ; 5 ; L_Mic ; 3
- db 05+pmCHANNELL+pmADMI ; 6 ; L_PCM ; 5
- db 06+pmCHANNELL+pmADMI ; 7 ; L_Spk ; 6
- db 00+pmCHANNELR+pmADMI ; 8 ; R_FM ; 0
- db 01+pmCHANNELR+pmADMI ; 9 ; R_Mix ; 1
- db 02+pmCHANNELR+pmADMI ; A ; R_Ext ; 2
- db 03+pmCHANNELR+pmADMI ; B ; R_Int ; 4
- db 04+pmCHANNELR+pmADMI ; C ; R_Mic ; 3
- db 05+pmCHANNELR+pmADMI ; D ; R_PCM ; 5
- db 06+pmCHANNELR+pmADMI ; E ; R_Spk ; 6
- db 07+pmCHANNELR+pmADMI ; F ; R_FREE; 7 - Now the SB connect
-
- SetMixer endp
-
- ;
- ; /*\
- ;---|*|----====< void SetVolume >====----
- ;---|*|
- ;---|*| This routine outputs a new setting for a volume channel.
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| AX is a register select value from 0 - 7
- ;---|*| BX is a value to be written to the control
- ;---|*| DS points to our data segment
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| AX,BX,CX,DX may be modified
- ;---|*|
- ; \*/
-
- public SetVolume
- SetVolume proc
- push es
- push di
- les di,mvhwShadowPointer ; get the pointer
-
- test [hardwaretype],bMVA508
- jjz _nsSetVolume
-
- xchg ax,bx ; ax = data, bx = channel
-
- and bl,10111111b ; knock out the Volume ID bit
-
- shl bx,1
- mov _voltbl[bx],ax ; save this channel's volume setting
- shr bx,1 ; restore bx & go
-
- mov ah,cs:mva508vol[bx] ; get the channel number for the MVA508
- xchg ah,al ; al = channel, ah = data
- cmp al,-1 ; is there an actual channel?
- jz sevo_exit ; no, just skip it...
- ;
- ; special case the loudness and enhanced stereo switches for the MVA508
- ;
- cmp bl,VOLLOUDENH AND 7 ; volume enhance switches?
- jnz @F ; no, continue on...
- shr ah,1 ; yes, swap the bit positions
- sbb dl,dl
- and dl,2
- or ah,dl
- shl ah,1
- ;
- @@:
- mov dx,pAUDIOMIXR ; parallel audio mixer interface
- dec dx
-
- push ax
- mov ah,al
- out dx,ax ; write the index
- pop ax
-
- xchg ah,al ; al = data, ah = channel
- mov ah,al
- out dx,ax ; write the data
-
- mov es:[di._paudiomixr],al ; shadow it...
- ;
- sevo_exit:
- pop di
- pop es
- ret
- ;
- ; National Semi's total volume control
- ;
- _nsSetVolume:
- xchg ax,bx ; ax = data, bx = channel
-
- and bl,10111111b ; knock out the Volume ID bit
- shl bx,1
-
- mov _voltbl[bx],ax ; save this channel's volume setting
-
- shr bx,1 ; restore bx & go
- or bl,01000000b ; replace the Volume ID bit
- mov ah,al ; ah = data
- call lvol ; call the read hardware routine
-
- jmp short sevo_exit
-
- ;
- ; MVA580 mixer channel assignments
- ;
- mva508vol label byte ; ch # ; PAS ; MVA508
- db 02+pmADDRSELECT+pmCHANNELLR; 0 ; MUTE ; VOLB
- db 05+pmADDRSELECT ; 1 ; LOUD/ENH ; 5
- db 03+pmADDRSELECT ; 2 ; BASS ; 3
- db 04+pmADDRSELECT ; 3 ; TREBLE ; 4
- db 01+pmADDRSELECT+pmCHANNELL ; 4 ; L-VOL ; 1,CC=01
- db 01+pmADDRSELECT+pmCHANNELR ; 5 ; R-VOl ; 1,CC=02
- db -1 ; 6 ; MODE ; N/A
- db -1 ; 7 ; N/A ; N/A
-
- SetVolume endp
-
- ;
- ;---------------------====================================---------------------
- ;---------------------====< Local Subroutine Section >====---------------------
- ;---------------------====================================---------------------
- ;
-
- ; /*\
- ;---|*|----====< FetchMixLevel >====----
- ;---|*|
- ;---|*| Remap mixer level from 0-31 into 0-12
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| AX holds the volume level - guarrenteed to be 0 - 31
- ;---|*| DS holds our data segment
- ;---|*|
- ;---|*| Exit Condtions:
- ;---|*| CY = 1, invalid volume level.
- ;---|*| CY = 0, good volume level.
- ;---|*| AH holds the converted value.
- ;---|*| AL the orig index.
- ;---|*|
- ; \*/
-
- public FetchMixLevel
- FetchMixLevel proc near
- ;
- ; ignore if the new mixer
- ;
- mov ah,al ; ah may return the whole thing
- test [HardwareType],bMVA508 ; if this is the MVA508
- jnz @F
- ;
- ; do the converion for the old mixer
- ;
- push bx
- push dx
- push ax
- ;
- ; remap 0-31 into 0-12: index = (index * 10) / 2.5
- ;
- mov dl,10
- mul dl
- mov dl,25
- div dl ; effectely divides 31 by 2.5
- ;
- ; read the table of hosed values
- ;
- mov bl,al
- sub bh,bh
-
- pop ax ; al holds the original index
- mov ah,mixersettings[bx] ; ah holds the real setting
-
- pop dx
- pop bx
- ;
- @@:
- clc
- ret
-
- FetchMixLevel endp
-
-
- ; /*\
- ;---|*|----====< lmix >====----
- ; \*/
-
- ;
- ; -- Load The Mixer
- ;
- ; Entry Conditions
- ; es:di point to the state table
- ; ah = index/data
- ; al = to mixer:
- ; al = INPUTMIXER (04h) - goes to input mixer
- ; al = OUTPUTMIXER (08h) - goes to output mixer
- ;
- ; Exit Conditions:
- ; No registers modified
- ;
- public lmix
- lmix proc near
- push ax
- push cx
- push dx
-
- disable ; make sure we clock in all data
- ;
- ; all clocks and ; strobes should be 1
- ;
- mov dx,AUDIOMIXR ; load mixer port
-
- mov al,es:[di._audiomixr] ; save the realsound & dual fm bits
-
- and al,bMIspkrint+bMImonofm
- or al,not (bMIspkrint+bMImonofm)
-
- mov cx,8 ; load bit count
- out dx,al ; set initial clocks
-
- @@: xor al,bMIclock ; toggle output mixer clock
- pause
- out dx,al ; output clock is zero
- ror al,1 ; make room for data
- ror ah,1 ; get bit of data
- adc al,al ; shift into register
- out dx,al ; send data to mixer
- xor al,bMIclock ; toggle clock again
- pause
- out dx,al ; clock sould be 1 now
- loop @B ; do all 8 bits this way
-
- xor al,bMImistrb ; toggle strobe low
- out dx,al ; which loads data into mixer
- pause
- xor al,bMImistrb ; toggle strobe high
- out dx,al ; loading complete
-
- mov es:[di._audiomixr],al ; save the last state
-
- enable
-
- pop dx
- pop cx
- pop ax
- ret
-
- lmix endp
-
- ;
- ; /*\
- ;---|*|----====< lvol >====----
- ; \*/
-
- ;
- ; lvol -- Load Volume control Register
- ;
- ; Entry Conditions:
- ; bl = parameter register (volume control channel 0-7)
- ; ah = data to transfer (new channel setting)
- ;
- ; Exit Conditions:
- ; AX,BX,CX,DX modified
- ;
- public lvol
- lvol proc near
- ;
- ; pass everything, but left/right volume directly to the device
- ;
- cmp bl,44h ; left & right volume are presented
- jz @F ; to the logical level as 0 - 40,
- cmp bl,45h ; where 0 is the lowest, and 40 is
- jnz lvolout ; the highest. In reality, this
- @@: sub ah,40 ; is backwards, that is, 40 is the
- neg ah ; lowest, and 0 is the highest. We will
- ; ; correct the value here...
- ; Perform the volume control output
- ;
- lvolout label near
- mov dx,AUDIOMIXR ; load mixer port
- ;
- ; all 1s but volume enable and clock
- ;
- mov al,es:[di._audiomixr] ; save the realsound & dual fm bits
-
- and al,bMIspkrint+bMImonofm
- or al,not (bMIspkrint+bMImonofm+bMIvol+bMIclock)
-
- disable ; do it all at once, no interruptions
-
- out dx,al ; set initial clocks
- mov cx,8 ; load bit count for address
- @@: xor al,bMIclock ; toggle volume control clock
- ror al,1 ; make room for data
- ror bl,1 ; get bit of data
- adc al,al ; shift into register
- out dx,al ; send data to volume control
- pause
- xor al,bMIclock ; toggle the clock again
- out dx,al ; clock should be 1 now
- loop @B ; do all 8 bits this way...
- xor al,bMIvol ; toggle volume control enable
- pause
- out dx,al ; which starts data loading
- mov cl,8 ; load bit count for data
- @@: xor al,bMIclock ; toggle volume control clock
- ror al,1 ; make room for data
- ror ah,1 ; get bit of data
- adc al,al ; shift into register
- out dx,al ; send data to volume control
- pause
- xor al,bMIclock ; toggle clock again
- out dx,al ; clock should be 1 now
- loop @B ; doall a 8 bits this way...
- pause
- mov cl,12 ; load bit count for data
- @@: out dx,al ; need to stall for 6 microseconds
- pause
- loop @B ; waiting...
- xor al,bMIvol ; toggle volume control enable
- out dx,al ; to prepare
- pause
- out dx,al ; need to stall
- pause
- out dx,al
- pause
- out dx,al
- pause
- xor al,bMIvol ; toggle volume control enable
- out dx,al ; which loads data
-
- mov es:[di._audiomixr],al ; save the last state
-
- enable
-
- ret
-
- lvol endp
-
- ;
- ;----====< rounduppct >====----
- ;
- rounduppct proc near
- cmp al,0 ; skip out if less than zero
- jle @F
- cmp al,100 ; skip out if greater/equal to 100
- jge @F
- inc al
- ;
- @@:
- ret
-
- rounduppct endp
-
-
- ; /*\
- ;---|*|----====< end of MIXERS.ASM >====----
- ; \*/
-
- end
-
-